/* 
 * Copyright (c) 2004-2005 Massachusetts Institute of Technology. This code was
 * developed as part of the Haystack (http://haystack.lcs.mit.edu/) research 
 * project at MIT. Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation files (the 
 * "Software"), to deal in the Software without restriction, including without 
 * limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom
 * the Software is furnished to do so, subject to the following conditions: 
 * 
 * The above copyright notice and this permission notice shall be included in 
 * all copies or substantial portions of the Software. 
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE. 
 */
/*
 * Created on Dec 19, 2004
 *
 */
package edu.mit.csail.relo.jdt.builder;

import org.apache.log4j.Logger;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IProjectNature;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;

import edu.mit.csail.relo.intro.ReloJavaConnectionUtils;
import edu.mit.csail.relo.jdt.ReloJDTPlugin;

/**
 * @author vineet
 *
 */
public class ReloJDTBuilderProjectNature implements IProjectNature {
    static final Logger s_logger = ReloJDTPlugin.getLogger(ReloJDTBuilderProjectNature.class);

	public static final String NATURE_ID = ReloJavaConnectionUtils.ReloJDTBuilder_NATURE_ID;
    
    private IProject project;
    

    /* (non-Javadoc)
     * @see org.eclipse.core.resources.IProjectNature#setProject(org.eclipse.core.resources.IProject)
     */
    public void setProject(IProject project) {
        this.project = project;
    }

    /* (non-Javadoc)
     * @see org.eclipse.core.resources.IProjectNature#getProject()
     */
    public IProject getProject() {
		return project;
    }

    /* (non-Javadoc)
     * @see org.eclipse.core.resources.IProjectNature#configure()
     */
    public void configure() throws CoreException {
    	try {
    		configureInternal();
    	} catch (Throwable t) {
    		s_logger.error("Unexpected error while configuring: " + this.getProject(), t);
    	}
    }
    public void configureInternal() throws CoreException {
    	s_logger.info("Configuring project nature: " + project);
        
        // connect the builder to the nature
        IProjectDescription descr = project.getDescription();
            
        ICommand builder  = descr.newCommand();
        builder.setBuilderName(ReloJDTBuilder.BUILDER_ID);
        
        ICommand builders[] = descr.getBuildSpec();
        
        for (int i = 0; i < builders.length; i++) {
            if (builders[i].getBuilderName().equals(ReloJDTBuilder.BUILDER_ID)) {
            	s_logger.warn("Nature already has builder associated with it!");
                return;
            }
        }

        ICommand newBuilders[] = new ICommand[builders.length+1];
        System.arraycopy(builders, 0, newBuilders, 0, builders.length);
        newBuilders[builders.length] = builder;
        
        descr.setBuildSpec(newBuilders);
		project.setDescription(descr, null);

		// launch the builder
        project.build(IncrementalProjectBuilder.FULL_BUILD, null);
		
		// verify - just in case
		if (!configured()) s_logger.error("Failed to configure builder for project nature");
    }

    /* (non-Javadoc)
     * @see org.eclipse.core.resources.IProjectNature#deconfigure()
     */
    public void deconfigure() throws CoreException {
    	try {
    		deconfigureInternal();
    	} catch (Throwable t) {
    		s_logger.error("Unexpected error while deconfiguring: " + this.getProject(), t);
    	}
    }
    private void deconfigureInternal() throws CoreException {
        s_logger.info("Deconfiguring project nature: " + project);

        // diconnect the bulider from the nature	
        IProjectDescription descr = project.getDescription();
        
        ICommand builders[] = descr.getBuildSpec();
        int index = -1;
        for (int i = 0; i < builders.length; i++) {
            if (builders[i].getBuilderName().equals(ReloJDTBuilder.BUILDER_ID)) {
                index = i;
                break;
            }
        }
        if (index == -1) {
        	s_logger.warn("Nature does not have a builder associated with it!");
            return;
        }
        
        ICommand newBuilders[] = new ICommand[builders.length-1];
        System.arraycopy(builders, 0, newBuilders, 0, index);
        System.arraycopy(builders, index+1, newBuilders, index, builders.length - index - 1);
        
        descr.setBuildSpec(newBuilders);
		project.setDescription(descr, null);

		// verify - just in case
		if (configured()) s_logger.error("Failed to de-configure builder for project nature");
        
		// launch the builder
        ReloJDTBuilder.clean(project);
    }

    public boolean configured() throws CoreException {
        IProjectDescription descr = project.getDescription();
        ICommand builders[] = descr.getBuildSpec();
        for (int i = 0; i < builders.length; i++) {
            if (builders[i].getBuilderName().equals(ReloJDTBuilder.BUILDER_ID)) {
                return true;
            }
        }
        return false;
    }

}
